"""项目生成命令模块"""

import argparse
from pathlib import Path
from src.core.command import Command
from src.base.registry import bera
from src.base.sql_file_utils import SQLFileUtils
from src.base.project_config import ProjectConfig
from src.commands.gen_code import GenCodeCommand

class GenProjectCommand(Command):
    """项目生成命令"""

    def __init__(self):
        super().__init__()
        self.name = "gen-project"
        self.group = "代码生成"
        self.help = "生成项目代码"
        self.description = """
        生成项目代码。该命令会:
        1. 初始化项目配置
        2. 复制基础代码
        3. 生成业务代码
        """

    def add_arguments(self, parser: argparse.ArgumentParser) -> None:
        """添加命令参数"""
        # 添加通用参数(filename/filepath/directory)
        SQLFileUtils.add_arguments(parser)

        # 添加工作目录参数
        parser.add_argument('-w', '--workspace_path', help='工作目录路径')

    def execute(self, args: argparse.Namespace) -> None:
        """执行命令"""
        try:
            bera.logger.info("开始执行gen-project命令")

            # 重置gen-code命令的会话时间戳，确保本次项目生成使用新的统一时间戳
            GenCodeCommand.reset_session_timestamp()

            # 初始化项目配置
            ProjectConfig.init(args.project_dir)

            # 临时处理:删除output-dir
            output_dir = ProjectConfig.get_output_dir()
            if output_dir.exists():
                # 安全检查:确保目录名以artifacts结尾
                if not output_dir.name.endswith('artifacts'):
                    bera.logger.warning(f"安全警告:output目录 {output_dir} 不以artifacts结尾,跳过删除")
                else:
                    try:
                        import shutil
                        bera.logger.info(f"清理output目录: {output_dir}")
                        shutil.rmtree(output_dir)
                        bera.logger.info("output目录清理完成")
                    except Exception as e:
                        bera.logger.error(f"清理output目录失败: {str(e)}")
                        # 清理失败不影响后续执行

            # 重置并设置SQL搜索路径
            SQLFileUtils.reset_search_paths()
            project_sql_dir = ProjectConfig.get_sql_dir()
            SQLFileUtils.add_search_path(str(project_sql_dir))

            # 确保工作目录存在
            workspace_path = self._get_workspace_path(args)
            SQLFileUtils.ensure_directory(workspace_path)

            # 复制基础代码
            self._copy_base_code(workspace_path)

            # 使用统一的输入模式处理
            SQLFileUtils.execute_file_processing(args, self._process_sql_file)

            bera.logger.info("gen-project命令执行完成")
        except Exception as e:
            if args.verbose:
                import traceback
                traceback.print_exc()
            SQLFileUtils.handle_file_error(e, Path(args.filepath) if args.filepath else None)

    def _get_workspace_path(self, args: argparse.Namespace) -> Path:
        """获取工作目录路径"""
        # 优先使用命令行参数
        if hasattr(args, 'workspace_path') and args.workspace_path:
            workspace_path = Path(args.workspace_path)
            # 如果是相对路径,转换为绝对路径
            if not workspace_path.is_absolute():
                workspace_path = Path.cwd() / workspace_path
            bera.logger.debug(f"使用命令行参数的工作目录: {workspace_path}")
            return workspace_path

        # 从项目配置中读取
        try:
            workspace_path = ProjectConfig.get_workspace_dir()
            bera.logger.debug(f"使用配置文件中的工作目录: {workspace_path}")
            return workspace_path
        except Exception as e:
            bera.logger.error(f"获取工作目录失败: {str(e)}")
            raise ValueError("无法获取工作目录,请检查配置文件中的workspace-dir配置项")

    def _copy_base_code(self, workspace_path: Path) -> None:
        """复制基础代码"""
        # 检查是否需要复制基础代码
        if not ProjectConfig.get_config().get('copy_base', True):
            bera.logger.info("配置指定不复制基础代码,跳过复制步骤")
            return

        # 获取基础代码目录
        base_dir = ProjectConfig.get_project_dir() / 'base'
        if not base_dir.exists():
            bera.logger.warning(f"基础代码目录不存在: {base_dir}")
            return

        # 复制基础代码
        SQLFileUtils.copy_directory(base_dir, workspace_path)
        bera.logger.info(f"基础代码复制完成: {base_dir} -> {workspace_path}")

    def _process_sql_file(self, filepath: str, args: argparse.Namespace) -> None:
        """处理单个SQL文件"""
        try:
            table_name = Path(filepath).stem
            bera.logger.info(f"🔄 gen-project 开始处理表: {table_name} (文件: {Path(filepath).name})")

            # 创建gen-code命令实例
            gen_code_cmd = GenCodeCommand()

            # 设置gen-code命令的参数
            gen_code_args = argparse.Namespace(
                filename=None,
                filepath=filepath,
                directory=None,
                project_dir=args.project_dir,
                verbose=args.verbose if hasattr(args, 'verbose') else False,
                workspace_path=args.workspace_path if hasattr(args, 'workspace_path') else None,
                template=None
            )

            # 执行gen-code命令
            gen_code_cmd.execute(gen_code_args)

            bera.logger.info(f"✅ gen-project 表处理成功: {table_name}")

        except Exception as e:
            bera.logger.error(f"❌ gen-project 处理SQL文件失败: {filepath}")
            if hasattr(args, 'verbose') and args.verbose:
                import traceback
                traceback.print_exc()
            raise e